//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;

namespace OpenLS.Chart.UI
{
    public class ChartPanel : Panel
    {
        public static readonly DependencyProperty PositionProperty =
            DependencyProperty.RegisterAttached("Position", typeof (LegendPosition), typeof (ChartPanel),
                                                new FrameworkPropertyMetadata(LegendPosition.Top,
                                                                              FrameworkPropertyMetadataOptions.
                                                                                  AffectsParentArrange));

        public static readonly DependencyProperty OverlayProperty =
            DependencyProperty.RegisterAttached("Overlay", typeof (bool), typeof (ChartPanel),
                                                new FrameworkPropertyMetadata(false,
                                                                              FrameworkPropertyMetadataOptions.
                                                                                  AffectsParentArrange));

        public static LegendPosition GetPosition(DependencyObject obj)
        {
            return (LegendPosition) obj.GetValue(PositionProperty);
        }

        public static void SetPosition(DependencyObject obj, LegendPosition value)
        {
            obj.SetValue(PositionProperty, value);
        }

        // Using a DependencyProperty as the backing store for Position.  This enables animation, styling, binding, etc...


        public static bool GetOverlay(DependencyObject obj)
        {
            return (bool) obj.GetValue(OverlayProperty);
        }

        public static void SetOverlay(DependencyObject obj, bool value)
        {
            obj.SetValue(OverlayProperty, value);
        }

        // Using a DependencyProperty as the backing store for Overlay.  This enables animation, styling, binding, etc...


        protected override Size MeasureOverride(Size constraint)
        {
            double maxWidth = 0.0;
            double maxHeight = 0.0;
            double totalWidth = 0.0;
            double totalHeight = 0.0;
            foreach (UIElement element in InternalChildren)
            {
                var availableSize =
                    new Size(Math.Max(0.0, (constraint.Width - totalWidth)),
                             Math.Max(0.0, (constraint.Height - totalHeight)));
                bool overlay = GetOverlay(element);
                element.Measure(availableSize);
                Size desiredSize = element.DesiredSize;
                switch (GetPosition(element))
                {
                    case LegendPosition.Left:
                    case LegendPosition.Right:
                        maxHeight = Math.Max(maxHeight, totalHeight + desiredSize.Height);
                        if (!overlay)
                            totalWidth += desiredSize.Width;
                        break;

                    case LegendPosition.Top:
                    case LegendPosition.Bottom:
                        maxWidth = Math.Max(maxWidth, totalWidth + desiredSize.Width);
                        if (!overlay)
                            totalHeight += desiredSize.Height;
                        break;
                    case LegendPosition.TopRight:
                        maxHeight = Math.Max(maxHeight, totalHeight + desiredSize.Height);
                        if (!overlay)
                            totalWidth += desiredSize.Width;
                        maxWidth = Math.Max(maxWidth, totalWidth + desiredSize.Width);
                        if (!overlay)
                            totalHeight += desiredSize.Height;
                        break;
                }
            }

            maxWidth = Math.Max(maxWidth, totalWidth);
            return new Size(maxWidth, Math.Max(maxHeight, totalHeight));
        }

        protected override Size ArrangeOverride(Size arrangeSize)
        {
            double x = 0.0;
            double y = 0.0;
            double rightWidth = 0.0;
            double bottomHeight = 0.0;
            int count = InternalChildren.Count;
            int i = 0;
            foreach (UIElement element in InternalChildren)
            {
                bool overlay = GetOverlay(element);
                Size desiredSize = element.DesiredSize;
                var finalRect = new Rect(x, y, Math.Max(0.0, arrangeSize.Width - (x + rightWidth)),
                                         Math.Max(0.0, arrangeSize.Height - (y + bottomHeight)));
                if (i < count - 1)
                {
                    switch (GetPosition(element))
                    {
                        case LegendPosition.Left:
                            x += desiredSize.Width;
                            finalRect.Width = desiredSize.Width;
                            if (overlay)
                                x -= desiredSize.Width;
                            break;

                        case LegendPosition.Top:
                            y += desiredSize.Height;
                            finalRect.Height = desiredSize.Height;
                            if (overlay)
                                y -= desiredSize.Height;
                            break;

                        case LegendPosition.Right:
                            rightWidth += desiredSize.Width;
                            finalRect.X = Math.Max(0.0, arrangeSize.Width - rightWidth);
                            finalRect.Width = desiredSize.Width;
                            if (overlay)
                                rightWidth -= desiredSize.Width;
                            break;

                        case LegendPosition.TopRight:
                            y += desiredSize.Height;
                            finalRect.Height = desiredSize.Height;
                            rightWidth += desiredSize.Width;
                            finalRect.X = Math.Max(0.0, arrangeSize.Width - rightWidth);
                            finalRect.Width = desiredSize.Width;
                            if (overlay)
                            {
                                y -= desiredSize.Height;
                                rightWidth -= desiredSize.Width;
                            }
                            break;

                        case LegendPosition.Bottom:
                            bottomHeight += desiredSize.Height;
                            finalRect.Y = Math.Max(0.0, arrangeSize.Height - bottomHeight);
                            finalRect.Height = desiredSize.Height;
                            if (overlay)
                                bottomHeight -= desiredSize.Height;
                            break;
                    }
                }
                element.Arrange(finalRect);
                i++;
            }

            return arrangeSize;
        }
    }
}